﻿using de.wolfmarco.pas.Shared.Interfaces;
using de.wolfmarco.pas.Shared.MessageBoxes;
using de.wolfmarco.pas.Shared.Regions;
using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Prism.Regions;
using System;
using System.Linq;
using System.Windows;
using System.Windows.Input;

namespace de.wolfmarco.pas.Shared.MVVM
{
    public class ModuleViewModel : ViewModelBase
    {
        protected readonly IRegionManager regionManager;
        protected readonly IModuleManager moduleManager;

        public delegate void ModuleRegionChangedEventHandler(object sender, RibbonTabEventArgs e);
        public event ModuleRegionChangedEventHandler ModuleRegionChanged;

        public ModuleViewModel(IRegionManager regionManager, IModuleManager moduleManager)
            : base()
        {
            this.regionManager = regionManager;
            this.moduleManager = moduleManager;

            ExitCommand = new DelegateCommand<object>(OnTryExit, CanExit);
            StartModuleCommand = new DelegateCommand<object>(OnTryStart, CanStart);
        }

        #region ExitCommand

        public DelegateCommand<object> ExitCommand { get; private set; }

        private void OnTryExit(object arg)
        {
            try
            {
                OnExit(arg);
            }
            catch (Exception ex)
            {
                PASMessageBox.ShowException(ex);
            }
        }

        protected virtual void OnExit(object arg)
        {
            Application.Current.MainWindow.Close();
        }

        protected virtual bool CanExit(object arg)
        {
            return true;
        }

        #endregion ExitCommand

        #region StartModuleCommand

        public DelegateCommand<object> StartModuleCommand { get; private set; }

        private void OnTryStart(object arg)
        {
            try
            {
                OnStart(arg);
            }
            catch (Exception ex)
            {
                PASMessageBox.ShowException(ex);
            }
        }

        protected virtual bool CanStart(object arg)
        {
            return true;
        }

        protected virtual void OnStart(object arg)
        {
            String uriString = StartView;

            ModuleInfo moduleInfo = arg as ModuleInfo;
            if (moduleInfo != null)
            {
                if (moduleInfo.State != ModuleState.Initialized)
                    moduleManager.LoadModule(moduleInfo.ModuleName);
                uriString = moduleInfo.ModuleName + "View";
            }

            regionManager.RequestNavigate(RegionNames.ModuleRegion, new Uri(uriString, UriKind.Relative), checkForError);

            if (ModuleRegionChanged != null)
            {
                RibbonTabEventArgs moduleEvent = new RibbonTabEventArgs(moduleInfo);
                ModuleRegionChanged(this, moduleEvent);

                foreach (IRibbonTab ribbonTab in moduleEvent.RibbonTabList)
                {
                    IRibbonTab ribbonTabView = RibbonRegion.Views.FirstOrDefault(view => view.GetType().Equals(ribbonTab.GetType())) as IRibbonTab;
                    bool isRibbonTabRegistered = (ribbonTabView != null);
                    bool sameModuleName = (ribbonTab.ModuleName == moduleInfo.ModuleName);

                    if (!isRibbonTabRegistered && sameModuleName)
                        regionManager.RegisterViewWithRegion(RegionNames.RibbonRegion, ribbonTab.GetType());
                    else if(isRibbonTabRegistered && !sameModuleName)
                        RibbonRegion.Remove(ribbonTab);
                }
            }
            else // Remove all RibbonTabs
                foreach (var view in RibbonRegion.Views)
                    RibbonRegion.Remove(view);
        }

        private IRegion RibbonRegion
        {
            get { return regionManager.Regions[RegionNames.RibbonRegion]; }
        }

        private string startView = "StartMenuModuleView";
        public string StartView
        {
            get { return startView; }
            set { startView = value; }
        }

        private void checkForError(NavigationResult result)
        {
            if (result.Result == false)
            {
                throw new Exception(result.Error.Message);
            }
        }

        #endregion StartModuleCommand
    }
}
